function isObject(value) {
  let valueType = typeof value
  return (value !== null) && (valueType == 'function' || valueType == 'object')
}

function deepCopy(originOption, map = new WeakMap()) {
  if(originOption instanceof Map) return originOption
  if(originOption instanceof Set) return originOption
  if(typeof originOption == 'function') return originOption

  if(map.has(originOption)) return map.get(originOption)

  if(!isObject(originOption)) return originOption
  let newObj = Array.isArray(originOption) ? [] : {}
  map.set(originOption, newObj)
  for(let key in originOption) {
    newObj[key] = deepCopy(originOption[key], map)
  }
  // symbol 处理
  return newObj
}

let obj = {
  name: 'jxh',
  age: function() {
    return 123
  },
  friend: {
    address: {
      place: '上海'
    }
  },
  joke: ['xjh1', 'xjh2'],
  map: new Map(),
}
obj.inner = obj

let newObj = deepCopy(obj) 
console.log(newObj == obj)
obj.friend.address.place = '北京'
console.log(newObj.friend.address.place)
console.log(newObj)

console.log(obj.inner.inner.inner)